/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Serveur;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

/**
 *
 * @author Florian
 */
public class FileServerWorker implements Runnable {

    private FileServer fs;
    private Socket s;

    public FileServerWorker(FileServer _fs, Socket _s) {
        this.s = _s;
        this.fs = _fs;
        new Thread(this).start();
    } // constructor(Socket)

    public void run() {
        DataInputStream in = null;
        DataOutputStream out = null;

        int calculChoisi;
        double annuite, montant, txInterets;
        int nbAnnees;

        fs.incrementActiveConnectionCount();
        System.out.println("Lancement du thread pour gérer"
                + "le protocole avec un client");

        // Lecture des paramètres nécessaires au calcul.
        try {
            //Récupération des données envoyées par le client
            in = new DataInputStream(s.getInputStream());
            out = new DataOutputStream(s.getOutputStream());

            //On récupère le calcul choisi par le client
            calculChoisi = in.readInt();
            switch (calculChoisi) {
                //Calcul de l'annuité
                case 1:
                    //On envoie le code de retour du serveur
                    out.writeInt(0);

                    //Récupération du montant
                    montant = in.readDouble();
                    if (!controleMontant(montant)) {
                        out.writeInt(2);
                    } else {
                        out.writeInt(0);
                    }

                    //Récupération du nombre d'année
                    nbAnnees = in.readInt();
                    if (!controleNbAnnees(nbAnnees)) {
                        out.writeInt(3);
                    } else {
                        out.writeInt(0);
                    }

                    //Récupération du taux d'interets
                    txInterets = in.readDouble();
                    if (!controleTauxInterets(txInterets)) {
                        out.writeInt(4);
                    } else {
                        //Calcul de la valeur de l'annuité
                        annuite = calculAnnuite(montant, nbAnnees, txInterets);
                        out.writeInt(0);
                        if (!fs.getGetShutDownFlag()) {
                            out.writeDouble(annuite);
                        }
                    }
                //Calcul du nombre d'années    
                case 2:
                    //On envoie le code de retour du serveur
                    out.writeInt(0);

                    //Récupération de l'annuite
                    annuite = in.readDouble();
                    if (!controleAnnuite(annuite)) {
                        out.writeInt(5);
                    } else {
                        out.writeInt(0);
                    }

                    //Récupération du taux d'interets
                    txInterets = in.readDouble();
                    if (!controleTauxInterets(txInterets)) {
                        out.writeInt(4);
                    } else {
                        out.writeInt(0);
                    }

                    //Récupération du montant de l'emprunt
                    montant = in.readDouble();
                    if (!controleMontant(montant)) {
                        out.writeInt(2);
                    } else {
                        //Calcul de la valeur de l'annuité
                        double nombreAnnees = calculNbAnnees(annuite, txInterets, montant);
                        out.writeInt(0);
                        if (!fs.getGetShutDownFlag()) {
                            out.writeDouble(nombreAnnees);
                        }
                    }

                //On retourne un code d'erreur pour le choix de calcul incorrect
                default:
                    out.writeInt(1);
            }
        } catch (IOException ioe) {
            System.err.println("Problème réseau d'E/S sur le serveur.");
        } finally {
            try {
                fs.decrementActiveConnectionCount();
                in.close();
                out.close();
                s.close();
            } catch (IOException ioe) {
                System.err.println("Problème réseau d'E/S sur le serveur.");
            }
        }
    }

    
    private double calculAnnuite(double montant, int nbAnnees, double txInteret) {
        txInteret = txInteret / 100;
        double puissance = Math.pow(1 + txInteret, nbAnnees);
        return montant * txInteret * (puissance / (puissance - 1));
    }

    private double calculNbAnnees(double annuite, double txInteret, double montant) {
        txInteret = txInteret / 100;
        double numerateur = Math.log(1 - ((txInteret * montant) / annuite));
        double denominateur = Math.log(1 + txInteret);
        return -(numerateur / denominateur);
    }
    
    private boolean controleMontant(double montant) {
        return (montant > 0);
    }

    private boolean controleTauxInterets(double txInterets) {
        return (txInterets > 0);
    }

    private boolean controleNbAnnees(int nbAnnees) {
        return (nbAnnees > 0);
    }

    private boolean controleAnnuite(double annuite) {
        return (annuite > 0);
    }
}
